package ginx

import (
	"common/configx"
	"fmt"
	sentrygin "github.com/getsentry/sentry-go/gin"
	"github.com/gin-gonic/gin"
)

type GinX struct {
	*gin.Engine
	Config        *configx.HttpConfig
	versionRoutes map[string]*gin.RouterGroup
}

type Opt func(g *GinX)

type GinGroupFunc func(g *gin.RouterGroup)

// WithHttpConfig http配置
func WithHttpConfig(config *configx.HttpConfig) Opt {
	return func(g *GinX) {
		g.Config = config
	}
}

// WithV1RouteGroup  v1路由
func WithV1RouteGroup(call GinGroupFunc) Opt {
	return func(g *GinX) {
		v1, ok := g.versionRoutes["v1"]
		if !ok {
			g.versionRoutes["v1"] = g.Group("v1")
			v1 = g.versionRoutes["v1"]
		}
		call(v1)
	}
}

// NewGinX 创建GinX客户端
func NewGinX(debug bool, opts ...Opt) *GinX {
	if debug {
		gin.SetMode(gin.DebugMode)
	} else {
		gin.SetMode(gin.ReleaseMode)
	}
	engine := gin.Default()
	g := &GinX{
		engine,
		nil,
		make(map[string]*gin.RouterGroup, 2),
	}
	for _, opt := range opts {
		opt(g)
	}
	return g
}

func (g *GinX) Connect() error {
	if err := g.Run(fmt.Sprintf("%s:%d", g.Config.Address, g.Config.Port)); err != nil {
		return err
	}
	return nil
}

func (g *GinX) Shutdown() error {
	return nil
}

// WithSentryMiddleware 设置gin的sentry收集器
func WithSentryMiddleware() Opt {
	return func(g *GinX) {
		g.Use(sentrygin.New(sentrygin.Options{}))
	}
}

// WithMiddleware 注册中间件
func WithMiddleware(middleware ...gin.HandlerFunc) Opt {
	return func(g *GinX) {
		g.Use(middleware...)
	}
}
